package com.smile.frame.seckill;


import com.smile.frame.common.result.Result;
import com.smile.frame.seckill.core.disruptor.SecondKillEvent;
import com.smile.frame.seckill.core.disruptor.SecondKillEventProducer;
import com.smile.frame.seckill.core.queqe.SecondKillQueue;
import com.smile.frame.seckill.core.queqe.TradeSecKillOrderCreateReq;
import com.smile.frame.seckill.service.SecondKillService;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;

// https://mp.weixin.qq.com/s/aCJUBpq_TiSaePCKokypFA
@Tag(name = "交易订单")
@RestController
@RequestMapping("/trade/order")
@Slf4j
public class TestTradeOrderController {

    @Resource
    private SecondKillEventProducer secondKillEventProducer;
    @Resource
    private SecondKillService secondKillService;


    private final ReentrantLock lock = new ReentrantLock();

    // 限流

    /**
     * 加锁防止超卖
     *
     * @return
     */
    @ApiOperation(value = "创建订单-Lock加锁")
    @PostMapping("/create/lock")
    public Result startLock() {
        // 在此处加锁
        lock.lock();
        try {
            log.info("创建订单-Lock加锁");
            final long userId = (int) (new Random().nextDouble() * (99999 - 10000 + 1)) + 10000;
            boolean result = secondKillService.startSecondKillByLock(1, userId);
            if (result) {
                log.info("用户:{}--{}", userId, "秒杀成功");
            } else {
                log.info("用户:{}--{}", userId, "哎呦喂，人也太多了，请稍后！");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 在此处释放锁
            lock.unlock();
        }
        return Result.ok();
    }

    /**
     * 加入阻塞队列更快响应
     *
     * @param req
     * @return
     */
    // https://mp.weixin.qq.com/s/aCJUBpq_TiSaePCKokypFA
    @PostMapping("/create/queue")
    @ApiOperation(value = "创建订单-BlockingQueue")
    public Result<String> createOrder(@RequestBody TradeSecKillOrderCreateReq req) {
        try {
            log.info("开创建订单-BlockingQueue");
            final long userId = (int) (new Random().nextDouble() * (99999 - 10000 + 1)) + 10000;
            req.setUserId(userId);
            req.setActivityId(1L);
            req.setSkuId(1L);
            req.setCount(1);
            Boolean flag = SecondKillQueue.getSkillQueue().produce(req);
            // 虽然进入了队列，但是不一定能秒杀成功 进队出队有时间间隙
            if (flag) {
                log.info("用户:{}{}", userId, "订单排队中");
            } else {
                log.info("用户:{}{}", userId, "秒杀失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.ok();
    }
    /**
     * 加入Disruptor高性能队列
     *
     * @return
     */
    @ApiOperation(value = "创建订单-Disruptor")
    @PostMapping("/create/disruptor")
    public Result<Void> createOrderDisruptor() {
        try {
            log.info("创建订单—Disruptor");
            final long userId = (int) (new Random().nextDouble() * (99999 - 10000 + 1)) + 10000;
            SecondKillEvent kill = new SecondKillEvent();
            kill.setSeckillId(1L);
            kill.setUserId(userId);
            secondKillEventProducer.producer(kill);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.ok();
    }

    // mq 异步处理订单
    // 校验+redis库存校验+发送创建订单+再次校验库存+入库+订单信息缓存+前端提示友好排队中，可轮询获取订单结果或websocket
//    https://mp.weixin.qq.com/s?__biz=MzU1NTA0NTEwMg==&mid=2247484580&idx=1&sn=5092e7d109b0f9bb9ed604fa03ac82cb&chksm=fbdb1d25ccac94338e39a6a36fab10dc36dd6a91a4e3cb0db1559cb82448865c4510b80a41ef&cur_album_id=1343916905417080833&scene=189#wechat_redirect


}
